#include "chooseditthemes.h"
#include "ui_chooseditthemes.h"
#include <QMessageBox>
#include <QFileDialog>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QTextStream>
#include <QProgressBar>
#include <QDebug>

ChoosEditThemes::ChoosEditThemes(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ChoosEditThemes)
{
    ui->setupUi(this);
    tmodel = new QSqlTableModel(this);
    tmodel->setTable("chooser_themes");
    tmodel->setSort(1, Qt::AscendingOrder);
    tmodel->setEditStrategy(QSqlTableModel::OnFieldChange);
    tmodel->select();
    tmodel->setHeaderData(1, Qt::Horizontal, tr("Theme name in English"));
    tmodel->setHeaderData(2, Qt::Horizontal, tr("Theme name in Hungarian"));
    ui->tableView_Themes->setModel(tmodel);
    ui->tableView_Themes->setColumnHidden(0, true);
    ui->tableView_Themes->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
    QRegExp rx("^(?!\\s)((?!\\*)(?!\\s\\s).)*$");
    newthemeEngValidator = new QRegExpValidator(rx, this);
    newthemeHunValidator = new QRegExpValidator(rx, this);
    ui->lineEdit_NewEnglish->setValidator(newthemeEngValidator);
    ui->lineEdit_NewHungarian->setValidator(newthemeHunValidator);
    fetchAllDataFromDB();
}

ChoosEditThemes::~ChoosEditThemes()
{
    delete tmodel;
    delete newthemeEngValidator;
    delete newthemeHunValidator;
    delete ui;
}

void ChoosEditThemes::fetchAllDataFromDB()
{
    while (tmodel->canFetchMore())
        tmodel->fetchMore();
}

void ChoosEditThemes::searchThisRow(int theme)
{
    for (int row = 0; row < tmodel->rowCount(); ++row) {
        QSqlRecord record = tmodel->record(row);
        if (record.value("tid").toInt() == theme) {
            ui->tableView_Themes->selectRow(row);
            break;
        }
    }
}

void ChoosEditThemes::on_actionNewThemeNamesChanged_triggered()
{
    int newEnLen = ui->lineEdit_NewEnglish->text().length();
    int newHuLen = ui->lineEdit_NewHungarian->text().length();
    if (newEnLen > 0 && newHuLen > 0)
        ui->pushButton_NewThemeSubmit->setEnabled(true);
    else
        ui->pushButton_NewThemeSubmit->setEnabled(false);
}

void ChoosEditThemes::on_pushButton_NewThemeSubmit_clicked()
{
    QString newEngString = ui->lineEdit_NewEnglish->text().trimmed();
    QString newHunString = ui->lineEdit_NewHungarian->text().trimmed();
    QSqlQuery query;
    query.prepare("INSERT INTO chooser_themes (teng, thun) "
                  "VALUES (:teng, :thun)");
    query.bindValue(":teng", newEngString);
    query.bindValue(":thun", newHunString);
    query.exec();
    ui->lineEdit_NewEnglish->clear();
    ui->lineEdit_NewHungarian->clear();
    tmodel->select();
    fetchAllDataFromDB();
    int id = query.lastInsertId().toInt();
    searchThisRow(id);
}

void ChoosEditThemes::on_pushButton_DeleteThemes_clicked()
{
    QItemSelectionModel *selectionModel = ui->tableView_Themes->selectionModel();
    QModelIndexList indexes = selectionModel->selectedRows();
    int selnr = indexes.count();
    if (!selnr) {
        QMessageBox::information(this, tr("No row selected"), tr("Not selected a row either."));
        return;
    }
    bool yesToAll = false;
    QMessageBox::StandardButtons questionButtons;
    if (selnr > 1)
        questionButtons = QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll;
    else
        questionButtons = QMessageBox::Yes | QMessageBox::No;
    for (int i = 0; i < selnr; ++i) {
        int row = indexes.at(i).row();
        int id = tmodel->record(row).value(0).toInt();
        QString themeName = tmodel->record(row).value(1).toString();
        QSqlQuery query;
        query.prepare("SELECT COUNT(*) FROM chooser WHERE tid=:thid");
        query.bindValue(":thid", id);
        query.exec();
        query.next();
        int cnt = query.record().value(0).toInt();
        int answer = 0;
        if (!yesToAll) {
            QString message(tr("Delete the theme: <b>"));
            message.append(themeName);
            message.append(tr("</b><br>and all (<b>%n</b>) tasks from this theme?", "", cnt));
            answer = QMessageBox::question(this, tr("Are you sure?"), message, questionButtons, QMessageBox::No);
        }
        if (answer == QMessageBox::YesToAll)
            yesToAll = true;
        if (answer == QMessageBox::NoToAll)
            break;
        if (yesToAll || answer == QMessageBox::Yes) {
            QSqlQuery delquery;
            delquery.prepare("DELETE FROM chooser WHERE tid=:thid");
            delquery.bindValue(":thid", id);
            delquery.exec();
            delquery.prepare("DELETE FROM chooser_themes WHERE tid=:thid");
            delquery.bindValue(":thid", id);
            delquery.exec();
        }
    }
    tmodel->select();
    fetchAllDataFromDB();
}

void ChoosEditThemes::on_pushButton_ImportFromfile_clicked()
{
    QString filename;
    filename = QFileDialog::getOpenFileName(this, tr("Choose input file for import themes and tasks"), QDir::currentPath(), tr("Text files (*.txt)"));
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QMessageBox::information(this, tr("Open error"), tr("Cannot open selected file."));
        return;
    }
    QTextStream in(&file);
    in.setCodec("UTF-8");
    QString line = in.readLine();
    if (line.compare(":AngolMix:CorrectChooser:", Qt::CaseInsensitive)) {
        QMessageBox::information(this, tr("File format error", "noheadline"), tr("The file is not compatible with CorrectChooser"));
        file.close();
        return;
    }
    int themesCnt = 0;
    int sentencesCnt = 0;
    int processedlineCnt = 1;
    int errorlinesCnt = 0;
    qint64 tpos = in.pos();
    line = in.readLine();
    if (line.compare("=")) {
        //file must begin with theme name
        QMessageBox::information(this, tr("File format error"), tr("The file must be start (after headline) with theme names"));
        return;
    }
    in.seek(tpos);
    int lastThemeID = 0;
    QProgressBar importProgress;
    importProgress.setFixedSize(240, 60);
    importProgress.setMaximum((int) file.size());
    importProgress.setWindowModality(Qt::ApplicationModal);
    importProgress.setWindowFlags(Qt::SplashScreen);
    importProgress.show();
    QSqlDatabase::database().transaction();
    while (!in.atEnd()) {
        line = in.readLine();
        ++processedlineCnt;
        importProgress.setValue((int) file.pos());
        QApplication::processEvents();
        if (line.compare("") == 0)
            continue;
        if (line.compare("=") == 0 ) {
            //new theme found
            line = in.readLine();
            ++processedlineCnt;
            QStringList splited = line.split("*");
            if (splited.count() != 2) {
                QMessageBox::information(this, tr("File format error"), tr("Error in themes processing at line %n.\nProcessing interrupted.", "", processedlineCnt));
                ++errorlinesCnt;
                break;
            }
            QSqlQuery addthemeQuery;
            QString thenStr(splited.at(0));
            QString thhuStr(splited.at(1));
            addthemeQuery.prepare("INSERT INTO chooser_themes (teng, thun) VALUES (:then, :thhu)");
            addthemeQuery.bindValue(":then", thenStr.simplified());
            addthemeQuery.bindValue(":thhu", thhuStr.simplified());
            addthemeQuery.exec();
            lastThemeID = addthemeQuery.lastInsertId().toInt();
            ++themesCnt;
        }
        else {
            //normal task row
            QStringList splited = line.split(QString("*"));
            if (splited.count() < 4 || splited.count() > 9) {
                ++errorlinesCnt;
                int answer = QMessageBox::question(this, tr("File format error"), tr("Error in tasks processing at line %n.\nContinue processing?", "", processedlineCnt), QMessageBox::Yes, QMessageBox::No);
                if (answer == QMessageBox::Yes)
                    continue;
                else
                    break;
            }
            QSqlQuery addsentenceQuery;
            QRegExp rx("[^1-9]");
            int r_type(splited.at(0).toInt());
            QString r_correct(splited.at(1));
            QString r_question(splited.at(2));
            QString r_answer1(splited.at(3));
            QString r_answer2 = "", r_answer3 = "", r_answer4 = "", r_answer5 = "", r_answer6 = "";
            QList<QString *> moreanswares;
            moreanswares << &r_answer2 << &r_answer3 << &r_answer4 << &r_answer5 << &r_answer6;
            for (int i = 4; i < splited.count(); ++i)
                moreanswares.at(i - 4)->append(splited.at(i));
            addsentenceQuery.prepare("INSERT INTO chooser (tid, type, correct, question, answer1, answer2, answer3, answer4, answer5, answer6)"
                                     " VALUES (:thid, :type, :correct, :question, :answer1, :answer2, :answer3, :answer4, :answer5, :answer6)");
            addsentenceQuery.bindValue(":thid", lastThemeID);
            addsentenceQuery.bindValue(":type", r_type);
            addsentenceQuery.bindValue(":correct", r_correct.simplified().remove(rx));
            addsentenceQuery.bindValue(":question", r_question.simplified());
            addsentenceQuery.bindValue(":answer1", r_answer1.simplified());
            addsentenceQuery.bindValue(":answer2", r_answer2.simplified());
            addsentenceQuery.bindValue(":answer3", r_answer3.simplified());
            addsentenceQuery.bindValue(":answer4", r_answer4.simplified());
            addsentenceQuery.bindValue(":answer5", r_answer5.simplified());
            addsentenceQuery.bindValue(":answer6", r_answer6.simplified());
            addsentenceQuery.exec();
            ++sentencesCnt;
        }
    }
    file.close();
    importProgress.hide();
    QString message;
    if (errorlinesCnt)
        message.append(tr("Import ready, but found errors in %n lines!\n", "", errorlinesCnt));
    else
        message.append(tr("Import ready for approve.\n"));
    message.append(tr("Themes: %n \n", "added themes nr", themesCnt));
    message.append(tr("Tasks: %n", "added tasks", sentencesCnt));
    int answer;
    answer = QMessageBox::question(this, tr("Are you sure?"), message, QMessageBox::Yes | QMessageBox::No);
    if (answer == QMessageBox::Yes)
        QSqlDatabase::database().commit();
    else
        QSqlDatabase::database().rollback();
    tmodel->select();
    fetchAllDataFromDB();
}

void ChoosEditThemes::on_pushButton_ExportTofile_clicked()
{
    QItemSelectionModel *selectionModel = ui->tableView_Themes->selectionModel();
    QModelIndexList indexes = selectionModel->selectedRows();
    int selnr = indexes.count();
    if (!selnr) {
        QMessageBox::information(this, tr("No items selected"), tr("Please highlight the rows to be exported!"));
        return;
    }
    QQueue<int> tIDlist;
    for (int i = 0; i < selnr; ++i) {
        int row = indexes.at(i).row();
        int id = tmodel->record(row).value(0).toInt();
        tIDlist.enqueue(id);
    }
    exportReallyProcessing(tIDlist);
}

void ChoosEditThemes::on_pushButton_ExportAllTofile_clicked()
{
    QSqlQuery query("SELECT tid FROM chooser_themes");
    QQueue<int> tIDlist;
    while (query.next())
        tIDlist.enqueue(query.record().value("tid").toInt());
    exportReallyProcessing(tIDlist);
}

void ChoosEditThemes::exportReallyProcessing(QQueue<int> &tIDs)
{
    QString filename;
    filename = QFileDialog::getSaveFileName(this, tr("Save to file"), QDir::currentPath(), tr("Text files (*.txt)"));
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QMessageBox::information(this, tr("Save error"), "Cannot save to selected file.");
        return;
    }
    QTextStream out(&file);
    out.setCodec("UTF-8");
    out << ":AngolMix:CorrectChooser:\n";
    int themesCnt = 0;
    int sentencesCnt = 0;
    while (tIDs.count()) {
        int id = tIDs.dequeue();
        QSqlQuery query;
        query.prepare("SELECT teng, thun FROM chooser_themes WHERE tid=:tid");
        query.bindValue(":tid", id);
        query.exec();
        query.next();
        QString thEngString = query.record().value("teng").toString();
        QString thHunString = query.record().value("thun").toString();
        //write theme row to file
        out << "=\n";
        out << thEngString << "*" << thHunString << "\n";
        ++themesCnt;
        query.prepare("SELECT type, correct, question, answer1, answer2, answer3, answer4, answer5, answer6 FROM chooser WHERE tid=:tid");
        query.bindValue(":tid", id);
        query.exec();
        while (query.next()) {
            QString w_type = query.record().value("type").toString();
            QString w_correct = query.record().value("correct").toString();
            QString w_question = query.record().value("question").toString();
            QString w_answer1 = query.record().value("answer1").toString();
            QString w_answer2 = query.record().value("answer2").toString();
            QString w_answer3 = query.record().value("answer3").toString();
            QString w_answer4 = query.record().value("answer4").toString();
            QString w_answer5 = query.record().value("answer5").toString();
            QString w_answer6 = query.record().value("answer6").toString();
            //write task to file
            out << w_type << "*" << w_correct << "*" << w_question << "*" << w_answer1 << "*" << w_answer2 << "*"
                << w_answer3 << "*" << w_answer4 << "*" << w_answer5 << "*" << w_answer6 << "\n";
            ++sentencesCnt;
        }
    }
    file.close();
    QString message(tr("Export completed successfully.\n"));
    message.append(tr("Themes: %n\n", "", themesCnt));
    message.append(tr("Tasks: %n", "", sentencesCnt));
    QMessageBox::information(this, tr("Export completed."), message);
}
